{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.session import GsSession\n",
    "# external users should substitute their client id and secret; please skip this step if using internal jupyterhub\n",
    "GsSession.use(client_id=None, client_secret=None, scopes=('run_analytics',)) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10x Binaries\n",
    "\n",
    "This screen shows how far a OTMS a 3m binary option must be struck to have a payout ratio of approximately 10:1. \n",
    "Normalized = % OTMS / 3m realized vol"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.timeseries import last_value, realized_volatility\n",
    "from gs_quant.markets.securities import AssetIdentifier, SecurityMaster\n",
    "from gs_quant.markets import PricingContext\n",
    "from gs_quant.instrument import FXBinary\n",
    "from gs_quant.target.common import OptionType\n",
    "from gs_quant.markets.portfolio import Portfolio\n",
    "from gs_quant.risk import FXSpot, Price\n",
    "from gs_quant.data import DataContext\n",
    "from gs_quant.api.gs.data import * \n",
    "import pandas as pd\n",
    "import warnings\n",
    "from datetime import date\n",
    "import matplotlib.pyplot as plt\n",
    "from gs_quant.datetime import business_day_offset\n",
    "from dateutil.relativedelta import relativedelta\n",
    "warnings.filterwarnings('ignore')\n",
    "pd.set_option('display.precision', 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Functions\n",
    "\n",
    "1) Calculating payout for binaries using defaults of 3m and 10:1\n",
    "\n",
    "\n",
    "2) Plot historical spot with call and put strikes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def payout_struck_binaries(crosses, payout_ratio='10%', tenor='3m', normalize=True, start_date=business_day_offset(business_day_offset(date.today(), -1, roll='forward') - relativedelta(years=1), -1, roll='forward')):\n",
    "    \"\"\"Prices FX Binaries for inputted crosses strike price using inputted payout ratio\n",
    "    \n",
    "    Screens for % OTMS for a given payout ratio\n",
    "    \n",
    "    : param crosses: array of string FX pairs e.g. ['USDJPY', 'USDNOK']\n",
    "    : param payout_ratio: string with % used to solve for strike price e.g 10% solves for a 10:1 payout ratio\n",
    "    : param tenor: FX Binary expiration date\n",
    "    : param normalize: divides % OTMS by realized volatility \n",
    "    : param start_date: start date for volatility history, if normalizing % OTMS, defaults to 1yr\n",
    "    \n",
    "    \"\"\"\n",
    "    binaries = Portfolio([FXBinary(pair=cross, expiration_date=tenor, option_type=direction, \n",
    "                                          strike_price=f'p={payout_ratio}', premium=0) \n",
    "                                 for direction in ('Call', 'Put') for cross in crosses])\n",
    "    with PricingContext():   \n",
    "        binaries.resolve()\n",
    "        spot = binaries.calc(FXSpot)            \n",
    "    bf = binaries.to_frame()\n",
    "    bf.index = bf.index.droplevel(0)\n",
    "    bf = bf[['pair', 'option_type', 'strike_price']]\n",
    "    bf['spot'] = list(spot)\n",
    "    bf['% otms'] = abs(bf.strike_price/bf.spot-1)*100\n",
    "    \n",
    "    #normalizing otms\n",
    "    if normalize:\n",
    "        df_vol = pd.DataFrame(columns=['pair','implied_vol'])\n",
    "        for cross in crosses:\n",
    "            asset = SecurityMaster.get_asset(cross, AssetIdentifier.BLOOMBERG_ID)\n",
    "            with DataContext(start=start_date, end=business_day_offset(date.today(), -1, roll='forward')): \n",
    "                vol = last_value(realized_volatility(asset, w=tenor))\n",
    "            df_vol = df_vol.append({'pair': f'{cross[:3]} {cross[3:]}', 'implied_vol': vol}, ignore_index=True)\n",
    "        bf = bf.merge(df_vol, left_on='pair', right_on='pair')\n",
    "        bf['normalized'] = bf['% otms'] / bf['implied_vol']\n",
    "    return bf.set_index(['option_type', 'pair']).sort_values(by=['option_type', '% otms'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_strikes(crosses, binaries, start_date=business_day_offset(business_day_offset(date.today(), -1, roll='forward') - relativedelta(years=2), -1, roll='forward')):\n",
    "    \"\"\"Plots historical spot for each FX pair and strike prices from FX Binary \n",
    "    \n",
    "    : param crosses: array of string FX pairs e.g. ['USDJPY', 'USDNOK']\n",
    "    : param binaries: Dataframe with crosses as index with strikes for both call and put FX Binary\n",
    "    : param start: start date for spot history, defaults to 2y\n",
    "    \n",
    "    \"\"\"\n",
    "    for cross in binaries.index.get_level_values('pair'):\n",
    "        with DataContext(start=start_date, end=business_day_offset(date.today(), -1, roll='forward')): \n",
    "            asset = SecurityMaster.get_asset(cross.replace(\" \", \"\"), AssetIdentifier.BLOOMBERG_ID)\n",
    "            q = GsDataApi.build_market_data_query(\n",
    "                [asset.get_marquee_id()],\n",
    "                QueryType.SPOT,\n",
    "                source=None,\n",
    "                real_time=False\n",
    "            )\n",
    "        spot = GsDataApi.get_market_data(q)\n",
    "        spot.plot()\n",
    "        plt.axhline(y=binaries.loc[(OptionType.Call, f'{cross}')]['strike_price'], color='g', label='Call Strike')\n",
    "        plt.axhline(y=binaries.loc[(OptionType.Put, f'{cross}')]['strike_price'], color='r', label='Put Strike')\n",
    "        plt.title(f'{cross} Binary')\n",
    "        plt.legend()\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 10X Binary Screen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "is_executing": true
    }
   },
   "outputs": [],
   "source": [
    "g10 = ['USDJPY', 'EURUSD', 'AUDUSD', 'GBPUSD', 'USDCAD', 'USDNOK', 'NZDUSD', 'USDSEK', 'USDCHF']\n",
    "\n",
    "results = payout_struck_binaries(crosses=g10)\n",
    "results.style.background_gradient(subset=['% otms'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "is_executing": true
    }
   },
   "outputs": [],
   "source": [
    "plot_strikes(g10, results, start_date=start_date)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
